package pl.edu.mimuw.irs.rcp.controller.editor.roles;

import org.eclipse.gef.EditDomain;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.PropertyDescriptor;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;

import pl.edu.mimuw.irs.core.model.design.resource.IHolder;
import pl.edu.mimuw.irs.core.model.design.resource.IMember;
import pl.edu.mimuw.irs.core.model.design.resource.RoleInstance;
import pl.edu.mimuw.irs.rcp.controller.editor.util.AbstractAdaptableDataWrapper;
import pl.edu.mimuw.irs.rcp.controller.editor.util.IMemberWrapper;
import pl.edu.mimuw.irs.rcp.util.MessageCode;
import pl.edu.mimuw.irs.rcp.util.UITexts;

public class AdaptableRoleInstanceWrapper extends AbstractAdaptableDataWrapper<RoleInstance> implements IMemberWrapper {

	// *** Attributes
	
	private RoleInstancePropertySource roleInstanceSource;
	private IHolder<RoleInstance> rolesHolder;
	public IHolder<RoleInstance> getRolesHolder() {
		return rolesHolder;
	}

	// *** Constructors

	public AdaptableRoleInstanceWrapper(RoleInstance role, IHolder<RoleInstance> rolesHolder, EditDomain editDomain) {
		super(role, editDomain);
		this.rolesHolder = rolesHolder;
	}
	
	// *** Methods
	
	@Override
	public IMember getMember() {
		return getData();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Object getAdapter(Class adapter) {
		if (adapter == IPropertySource.class) {
			if (roleInstanceSource == null) {
				roleInstanceSource = new RoleInstancePropertySource(
						getData().getModifier());
			}
			return roleInstanceSource;
		}
		return null;
	}
	
	public class RoleInstancePropertySource implements IPropertySource {

		// *** Attributes
		
		private static final String PROPERTY_COST = "properties.roleinstance.cost";
		private static final String PROPERTY_EXTERNAL_COST = "properties.roleinstance.external.cost";
		
		private IPropertyDescriptor[] propertyDescriptors;
		
		private Double defaultCost;
		
		// *** Constructors
		
		public RoleInstancePropertySource(Double defaultCost) {
			this.defaultCost = defaultCost;
		}
	
		// *** Methods
		
		@Override
		public Object getEditableValue() {
			return null;
		}

		@Override
		public IPropertyDescriptor[] getPropertyDescriptors() {
			if (propertyDescriptors == null) {
	            // Create a descriptors and set a category
	            PropertyDescriptor costDescriptor = 
	            	new TextPropertyDescriptor(PROPERTY_COST, UITexts.get(MessageCode.PROPERTIES_FIELD_COST_TIME));
	            costDescriptor.setCategory(UITexts.get(MessageCode.PROPERTIES_CATEGORY_CUSTOM));
	            
	            PropertyDescriptor externalCostDescriptor = 
	            	new PropertyDescriptor(PROPERTY_EXTERNAL_COST, UITexts.get(MessageCode.PROPERTIES_FIELD_COST_TIME));
	            externalCostDescriptor.setCategory(UITexts.get(MessageCode.PROPERTIES_CATEGORY_EXTERNAL));

	            propertyDescriptors = new IPropertyDescriptor[] { 
	            		costDescriptor, externalCostDescriptor };
            }
            return propertyDescriptors;
		}

		@Override
		public Object getPropertyValue(Object id) {
			if (PROPERTY_COST.equals(id)) {
				return String.valueOf(getData().getModifier());
			} else if (PROPERTY_EXTERNAL_COST.equals(id)) {
				if (getData().getCalculatedModifier() == null) return UITexts.get(MessageCode.PROPERTIES_VALUE_UNKNOWN);
				else return String.valueOf(getData().getCalculatedModifier());
			}
			return null;
		}

		@Override
		public boolean isPropertySet(Object id) {
			if (PROPERTY_COST.equals(id)) {
	        	String curValue = (String)getPropertyValue(id);
				return !curValue.equals(defaultCost);
			}
			return false;
		}

		@Override
		public void resetPropertyValue(Object id) {
			if (PROPERTY_COST.equals(id)) {
				setPropertyValue(id, defaultCost);
			}
		}

		@Override
		public void setPropertyValue(Object id, Object value) {
			if (PROPERTY_COST.equals(id)) {
				try {
					getData().setModifier(Double.valueOf((String)value));
				} catch (NumberFormatException nfe) {}
			}
		}
		
	}
}
